package cms.simmytech.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;

import cms.simmytech.service.MyAccessDeniedHandler;
import cms.simmytech.service.MyFilterSecurityInterceptor;

/**
 * Created by yangyibo on 17/1/18.
 */

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private MyFilterSecurityInterceptor myFilterSecurityInterceptor;

	@Autowired
	UserDetailsService customUserService;

	@Autowired
	DataSource dataSource;

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(customUserService).passwordEncoder(new MyPasswordEncoder()); // user
		                                                                                     // Details
		                                                                                     // Service验证

	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.headers().frameOptions().disable().and().authorizeRequests()
		        .antMatchers("/dist/**", "/plugins/**", "/favicon.ico", "/defaultKaptcha", "/common/**").permitAll().anyRequest().authenticated() // 任何请求,登录后可以访问
		        .and().formLogin().loginPage("/login").defaultSuccessUrl("/").failureUrl("/login?error").permitAll() // 登录页面用户任意访问
		        .and().logout().permitAll()// 注销行为任意访问
		        .and().rememberMe().rememberMeServices(rememberMeServices()).key("INTERNAL_SECRET_KEY").userDetailsService(customUserService);
		http.addFilterBefore(new KaptchaAuthenticationFilter("/login", "/login?error"), UsernamePasswordAuthenticationFilter.class);
		http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
		http.exceptionHandling().accessDeniedHandler(getAccessDeniedHandler());
		// 开启CORS，关闭CSRF跨域
		http.cors().and().csrf().disable();
//		http.antMatcher("/common/**").authorizeRequests().antMatchers("/common/upload_file").permitAll().anyRequest().authenticated();
	}

	@Bean
	public AccessDeniedHandler getAccessDeniedHandler() {
		return new MyAccessDeniedHandler();
	}

	@Bean
	public RememberMeServices rememberMeServices() {
		JdbcTokenRepositoryImpl rememberMeTokenRepository = new JdbcTokenRepositoryImpl();
		// 此处需要设置数据源，否则无法从数据库查询验证信息
		rememberMeTokenRepository.setDataSource(dataSource);

		// 此处的 key 可以为任意非空值(null 或 "")，单必须和起前面
		// rememberMeServices(RememberMeServices
		// rememberMeServices).key(key)的值相同
		PersistentTokenBasedRememberMeServices rememberMeServices = new PersistentTokenBasedRememberMeServices("INTERNAL_SECRET_KEY",
		        customUserService, rememberMeTokenRepository);

		// 该参数不是必须的，默认值为 "remember-me", 但如果设置必须和页面复选框的 name 一致
		rememberMeServices.setParameter("remember-me");
		return rememberMeServices;
	}

}
